﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTO.Common;
using ServiceInterfaces.Stores;
using System.ServiceModel;
using DAO.Stores;
using ServiceImplementation.Common;
using System.Transactions;

namespace Stores
{

    [ServiceBehavior(
        ReleaseServiceInstanceOnTransactionComplete= true,
        TransactionAutoCompleteOnSessionClose = true,
        TransactionIsolationLevel = IsolationLevel.ReadCommitted,
        IncludeExceptionDetailInFaults=true)]
    class Store : IStoreSales, IStoresManagement, IStoresManagementMSMQ
    {

        #region IStoreSales

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void Sell(List<SoldProduct> products)
        {
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("Sell");

            bool sold = true;
            ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
            foreach (SoldProduct product in products)
            {
                sold = productDAO.DecreaseProductStock(product.Product.Code, product.Amount);
                if (!sold)
                {
                    string reason = string.Format("The product {0} is not available on stock.", product.Product.Code);
                    CannotSellProductException exception = new CannotSellProductException(reason);
                    throw new FaultException<CannotSellProductException>(exception, new FaultReason(reason));
                }
            }
        }

        //[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        //public List<ProductAvailability> CheckAvailability(List<SoldProduct> products)
        //{
        //    Console.WriteLine("-------------------------------------------");
        //    Console.WriteLine("CheckAvailability");

        //    List<ProductAvailability> availability = new List<ProductAvailability>();

        //    ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
        //    foreach (SoldProduct product in products)
        //    {
        //        int stock = productDAO.GetProductStock(product.Product.Code);
        //        ProductAvailability productAvailability = new ProductAvailability { 
        //            AmountAvailable = stock,
        //            Available = stock >= product.Amount,
        //            Product = product.Product
        //        };

        //        availability.Add(productAvailability);
        //    }

        //    return availability;
        //}

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public List<Product> CheckAvailability(List<SoldProduct> products)
        {
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("CheckAvailability");

            List<Product> productList = new List<Product>();

            ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
            foreach (SoldProduct product in products)
            {
                Product p = productDAO.GetProduct(product.Product.Code);
                productList.Add(p);
            }

            return productList;
        }

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public ProductList GetProducts(int page, int recordsPerPage)
        {
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("GetProducts");
            Console.WriteLine(string.Format("\tpage = {0} recordsPerPage = {1}", page, recordsPerPage));

            ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
            return new ProductList { 
                Products = productDAO.GetProducts(page, recordsPerPage),
                Total = productDAO.GetNumberOfProducts()
            }; 
        }
        
        #endregion 

        #region IStoresManagement

        public void UpdateProductStock(int productCode, int amount)
        {
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("UpdateProductStock");
            Console.WriteLine(string.Format("\tproductCode = {0} amount = {1}", productCode, amount));

            ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
            productDAO.AddProductStock(productCode, amount);
        }

        #endregion

        #region IStoresManagementMSMQ

        [OperationBehavior(TransactionAutoComplete=true, TransactionScopeRequired = true)]
        public void AddProduct(Product product)
        {
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("AddProduct");
            Console.WriteLine(product.ToString());

            ProductDAO productDAO = new ProductDAO(ConfigSettings.provider, ConfigSettings.connectionString);
            productDAO.AddProduct(product);
        }

        #endregion
    }
}
